﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Needle.DevToolkit.Services;
using System.Windows.Forms;
using System.IO;
using Needle.Utils;
using Needle.Utils.Extensions;

namespace Needle.DevToolkit.Services.UI
{
    public class UIService : ServiceBase, IUIService, IFileChooser, IFormManager
    {

        private OpenFileDialog _openFileDialog;
        private OpenFileDialog OpenFileDialog
        {
            get
            {
                if (_openFileDialog == null)
                    _openFileDialog = new OpenFileDialog();
                return _openFileDialog;
            }
        }

        private SaveFileDialog _saveFileDialog;
        private SaveFileDialog SaveFileDialog
        {
            get
            {
                if (_saveFileDialog == null)
                    _saveFileDialog = new SaveFileDialog();
                return _saveFileDialog;
            }
        }

        private Form _mainForm;

        public UIService(IServiceProvider serviceProvider, Form mainForm)
            : base(serviceProvider)
        {
            if (serviceProvider == null)
                throw new ArgumentNullException("serviceProvider", "serviceProvider is null.");
            if (mainForm == null)
                throw new ArgumentNullException("mainForm", "mainForm is null.");
            _mainForm = mainForm;
        }

        public void ShowError(string errorTitle, string errorMessage, Exception ex)
        {
            MessageBox.Show(_mainForm, errorMessage, errorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        public void ShowMessage(string msgTitle, string msg)
        {
            MessageBox.Show(_mainForm, msg, msgTitle, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        public string ChooseSingleFile(string initialPath, string fileFilter, System.IO.FileAccess access)
        {
            IList<string> fileNames = ChooseFiles(initialPath, fileFilter, false, access);
            if (fileNames.Count > 0)
                return fileNames[0];
            return null;

        }

        public string[] ChooseMultipleFiles(string initialPath, string fileFilter, System.IO.FileAccess access)
        {
            IList<string> fileNames = ChooseFiles(initialPath, fileFilter, true, access);
            if (fileNames.Count > 0)
                return fileNames.ToArray();
            return null;
        }

        public string ChooseFolder(string initialPath)
        {
            var dialog = new FolderBrowserDialog();
            dialog.ShowNewFolderButton = true;
            if (Directory.Exists(initialPath))
                dialog.SelectedPath = initialPath;
            if (DialogResult.OK == dialog.ShowDialog(_mainForm))
            {
                return dialog.SelectedPath;
            }
            return null;
        }

        public void ShowForm<T>() where T : Form
        {
            var form = Services.GetService<IComponentLoader>().LoadComponent<T>();
            ShowForm(form);
        }

        public void ShowForm(Form form)
        {
            ApplyFormStyle(form);
            form.Show();
        }

        public DialogResult ShowDialog(Form form)
        {
            ApplyDialogStyle(form);
            return form.ShowDialog();
        }

        private IList<String> ChooseFiles(string initialPath, string fileFilter, bool multiSelect, System.IO.FileAccess access)
        {
            List<string> selectedFiles = new List<string>();

            if (!AppFileSystem.LocalDataFolder.Exists)
                AppFileSystem.LocalDataFolder.Create();

            switch (access)
            {
                case System.IO.FileAccess.Read:
                case System.IO.FileAccess.ReadWrite:

                    OpenFileDialog.Multiselect = multiSelect;

                    if (Directory.Exists(initialPath))
                        OpenFileDialog.InitialDirectory = initialPath;

                    if (File.Exists(initialPath))
                        OpenFileDialog.FileName = initialPath;

                    OpenFileDialog.Filter = fileFilter;
                    OpenFileDialog.CustomPlaces.Add(new FileDialogCustomPlace(AppFileSystem.LocalDataFolder.FullName));

                    if (DialogResult.OK == OpenFileDialog.ShowDialog(_mainForm))
                        if (multiSelect)
                            selectedFiles.Add(OpenFileDialog.FileName);
                        else
                            selectedFiles.AddRange(OpenFileDialog.FileNames);

                    break;
                case System.IO.FileAccess.Write:


                    if (Directory.Exists(initialPath))
                        SaveFileDialog.InitialDirectory = initialPath;

                    if (File.Exists(initialPath))
                        SaveFileDialog.FileName = initialPath;

                    SaveFileDialog.Filter = fileFilter;
                    SaveFileDialog.CustomPlaces.Add(new FileDialogCustomPlace(AppFileSystem.LocalDataFolder.FullName));
                    if (DialogResult.OK == SaveFileDialog.ShowDialog(_mainForm))
                        selectedFiles.Add(SaveFileDialog.FileName);

                    break;
            }
            return selectedFiles;
        }

        private void ApplyFormStyle(Form form)
        {
            form.Owner = _mainForm;
            form.TopMost = false;
            form.ShowIcon = false;
            form.ShowInTaskbar = false;
            form.StartPosition = FormStartPosition.CenterParent;

        }

        private void ApplyDialogStyle(Form form)
        {
            ApplyFormStyle(form);
            form.MaximizeBox = false;
            form.MinimizeBox = false;
        }
        
        protected override Type[] ExposedServices
        {
            get
            {
                return new Type[] 
                { 
                    typeof(IUIService), 
                    typeof(IFileChooser), 
                    typeof(IFormManager) 
                };
            }
        }
    }
}
